##########################################
## Copyright 2012-2013 Ceruti Francesco
##
##
## This file is part of LiSP (Linux Show Player).
##
## LiSP (Linux Show Player) is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## LiSP (Linux Show Player) is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with LiSP (Linux Show Player).  If not, see <http://www.gnu.org/licenses/>.
##########################################

import socket
import time
import threading
from lisp.core.events import Event


class Slave:

    def __init__(self, masterAddr, slavePort):
        self.masterAddr = masterAddr
        self.syncCmd = Event()
        self.activeSlave = Event()
        self.sSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sSocket.bind(('', slavePort))
        self.sSocket.listen(16)
        self.acceptThread = threading.Thread(None, target=self.listen)
        self.acceptThread.setDaemon(True)
        self.acceptThread.start()

        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(self.masterAddr)
            sock.send(bytes('SLAVE', 'UTF-8'))
            sock.close()
        except Exception as e:
            print(masterAddr, ': ', e)

        self.pingThread = threading.Thread(None, target=self.ping)
        self.pingThread.setDaemon(True)
        self.pingThread.start()

    def listen(self):
        while(True):
            try:
                conn = self.sSocket.accept()[0]
                data = str(conn.recv(1024), 'UTF-8')
                self.syncCmd.emit(data)
                conn.close()
            except:
                pass

    def ping(self):
        try:
            while(True):
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect(self.masterAddr)
                sock.send(bytes('PING', 'UTF-8'))
                time.sleep(0.2)
                sock.close()
        except:
            self.activeSlave.emit()
